package com.wcy.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wcy.annotation.aop.PreAuth;
import com.wcy.entity.User;
import com.wcy.entity.UserRole;
import com.wcy.entity.queryVo.QueryConvertor;
import com.wcy.entity.userVo.AuthorProfile;
import com.wcy.entity.userVo.PasswordObject;
import com.wcy.entity.userVo.UserFiltered;
import com.wcy.service.IUserRoleService;
import com.wcy.service.IUserService;
import com.wcy.util.JwtTokenUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private IUserService userService;
    @Resource
    private IUserRoleService userRoleService;
    @Resource
    private JwtTokenUtil tokenUtil;

    @PreAuth("USER:QUERY")
    @GetMapping("/page")
    @SentinelResource(value = "#root.targetClass + '.' + #root.methodName")
    public ResponseEntity<Page<User>> getPage(@RequestParam(defaultValue = "1") int pageNum,
                                              @RequestParam(defaultValue = "10") int pageSize,
                                              HttpServletRequest request) {
        String queryData = request.getHeader("X-Query-Data");
        QueryWrapper wrapper = new QueryConvertor(queryData).convert(true);
        Page<User> page = userService.page(new Page<>(pageNum, pageSize), wrapper);
        return ResponseEntity.ok(page);
    }

    @PreAuth("USER:QUERY")
    @GetMapping("/list")
    @SentinelResource(value = "#root.targetClass + '.' + #root.methodName")
    public ResponseEntity<List<User>> getList(HttpServletRequest request) {
        String queryData = request.getHeader("X-Query-Data");
        QueryWrapper wrapper = new QueryConvertor(queryData).convert(true);
        List<User> list = userService.list(wrapper);
        return ResponseEntity.ok(list);
    }

    @PreAuth("USER:ADD")
    @Transactional
    @PostMapping("/add")
    @SentinelResource(value = "#root.targetClass + '.' + #root.methodName")
    public ResponseEntity<Void> add(@RequestBody User user) {
        userRoleService.replaceUserRole(user);
        userService.save(user);
        return ResponseEntity.ok().build();
    }

    @PreAuth("USER:ALTER")
    @Transactional
    @PutMapping("/update")
    @SentinelResource(value = "#root.targetClass + '.' + #root.methodName")
    public ResponseEntity<Void> update(@RequestBody User user) {
        userRoleService.replaceUserRole(user);
        userService.updateById(user);
        return ResponseEntity.ok().build();
    }
    @PreAuth("AUTHENTICATION")
    @PutMapping("/updateProfile")
    @SentinelResource(value = "#root.targetClass + '.' + #root.methodName")
    public ResponseEntity<UserFiltered> updateProfile(@RequestBody User user,HttpServletRequest request) {
        Integer userId = tokenUtil.getUserIdFromToken(tokenUtil.getToken(request));
        user.setUserId(userId);
        if(userService.updateById(user)){
            return ResponseEntity.ok(new UserFiltered(userService.getOne(new QueryWrapper<User>().eq("user_id",userId))));
        }
        return ResponseEntity.badRequest().build();
    }

    @GetMapping("/getProfile")
    @SentinelResource(value = "#root.targetClass + '.' + #root.methodName")
    public ResponseEntity<UserFiltered> getProfile(HttpServletRequest request) {
        Integer userId = tokenUtil.getUserIdFromToken(tokenUtil.getToken(request));
        return ResponseEntity.ok(new UserFiltered(userService.getOne(new QueryWrapper<User>().eq("user_id",userId))));
    }

    @DeleteMapping("/delete/{id}")
    @SentinelResource(value = "#root.targetClass + '.' + #root.methodName")
    public ResponseEntity<Void> delete(@PathVariable Integer id) {
        userService.removeById(id);
        return ResponseEntity.ok().build();
    }

    @GetMapping("/{id}")
    public ResponseEntity<UserFiltered> getUser(@PathVariable("id") Integer id){
        if(!userService.exists(new QueryWrapper<User>().eq("user_id",id)))
            return ResponseEntity.ok(new UserFiltered());
        return ResponseEntity.ok(new UserFiltered(userService.getById(id)));
    }

    @PostMapping("/authorProfile")
    public ResponseEntity<AuthorProfile> getAuthorProfile(@RequestBody List<Integer> ids){
        return ResponseEntity.ok(userService.getAuthorProfile(ids));
    }

    @PreAuth("AUTHENTICATION")
    @GetMapping("/isAuthor")
    public ResponseEntity<Boolean> hasAuthor(HttpServletRequest request){
        return ResponseEntity.ok(userRoleService.exists(new QueryWrapper<UserRole>().eq("user_id",tokenUtil.getUserIdFromToken(tokenUtil.getToken(request))).eq("role_id",4)));
    }

    @PreAuth("AUTHENTICATION")
    @PostMapping("/becomeAuthor")
    public ResponseEntity<Boolean> becomeAuthor(HttpServletRequest request){
        return ResponseEntity.ok(userRoleService.save(new UserRole(tokenUtil.getUserIdFromToken(tokenUtil.getToken(request)),4)));
    }

    @PreAuth("AUTHENTICATION")
    @PostMapping("/alterPassword")
    public ResponseEntity<String> alterPassword(@RequestBody PasswordObject passwordObject,HttpServletRequest request){
        Integer userId = tokenUtil.getUserIdFromToken(tokenUtil.getToken(request));
        return userService.updatePassword(passwordObject, userId)?ResponseEntity.ok("修改成功"):ResponseEntity.badRequest().body("修改失败");
    }
}